/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package lintulaskenta.pulautin;

import java.nio.charset.Charset;
import lintulaskenta.entity.Havainnointitapahtuma;
import lintulaskenta.entity.Havaintopiste;
import lintulaskenta.entity.Lajihavainto;
import lintulaskenta.entity.Parvihavainto;
import lintulaskenta.entity.Pistevuosi;
import lintulaskenta.entity.Reitti;
import java.io.*;
import java.util.*;

/*
 * Pulautin lukee vanhaa perättäisdataa yhden Reittikokonaisuuden kerrallaan.
 * Pulautinta ajetaan PulauttimenAjajalla.
 * Perättäisdatan lukuohjeet:

ReitinNumero            (sar. 1-4)
Vuosi                   (sar. 5-8)
RivinJuoksevaNumero	(sar. 9-10)

REITIN ENSIMMÄISELLÄ RIVILLÄ ON:

HavainnoijaNumero	(sar. 11-14) (linnustonseurannan havainnoijanumero 0001-9999)
PenikulmaRuutu          (sar. 15-19) (yht. koord., NNNEE, siis ilman tunnuskolmosta)
KuntaLyhenne            (sar. 20-25) (enintään 6 kirjainta)
PisteidenLukumäärä	(sar. 26-27) (tavallisesti 20)
LähempiPaikka           (sar. 28-44) (enintään 17 kirjainta)
TalviReitinNumero	(sar. 45-48) (reitti, johon pistelaskenta mahdollisesti yhtyy)
LaskentaPäivä           (sar. 49-50) (maksimi 31)
LaskentaKuukausi	(sar. 51)    (arvot 5, 6 tai 7)
LaskentaAlkoi           (sar. 52-55) (TTMM, tunnit ja minuutit)
LaskentaLoppui          (sar. 56-59)

EnsimmäisenParvenPiste	(60-61) (Piste, jossa parvi havaittiin)
EnsimmäisenParvenLaji	(62-67) (6 kirjaimen lyhenne)
EnsimmäisenParvenKoko	(68-70) (lintumäärä)

ToisenParvenPiste	(71-72) (Piste, jossa parvi havaittiin)
ToisenParvenLaji	(73-78) (6 kirjaimen lyhenne)
ToiseParvenKoko         (79-81) (lintumäärä)

Jos parvihavaintoja on 3-6 (ei voi olla enempää), on 1. rivillä sarakkeessa 82 '*', ja seuraavalla sivulla on:

3.parvi  4.parv  5.parv 6.parvi
piste 11-12  22-23   33-34  44-45
lajilyh. 13-18  24-29   35-40  46-51
määrä  19-21  30-32   41-43  52-54

REITIN ENSIMMÄISELLÄ PISTETIETORIVILLÄ) on:

BiotooppiKoodi          (sar. 11-12)
BiotooppiKoodiEnnen	(sar. 13-14)
PisteenNumero           (sar. 15-16)

Kahdeksan lajihavaintoa sarakkeissa 17-80 muodossa 8*(SULLLLLL),
missä S ja U ovat parimäärä 50 m säteen sisä- ja ulkopuolella
(kumpaankin mahtuu yksinumeroinen tieto) ja LLLLLL = lajin kuuden
kirjaimen lyhenne (isot aakkoset).
 *
 */
public class PulautinV3 extends Observable {
    private static final char tahti = '*';
    private static final char nolla = '0';
    private static int jatkoriveja = 0;
    private static String jatkorivi;
    private static BufferedReader buffreader;
    private static final Charset charset = Charset.forName("ISO-8859-1");
    private static Havainnointitapahtuma ht = new Havainnointitapahtuma();
    private static Havainnointikokonaisuus hk = new Havainnointikokonaisuus();
    private static Pistevuosi pv;
    private static Havaintopiste hp;
    private static Reitti rt = new Reitti();
    private static boolean reittiVaihtunut = true;
    private static int aikaisempiParsittavaReitti = -1;
    private static boolean onkoDataLoppunut = false;
    private static boolean lukeminenAloitettu = false;
    private static int edellinenItakoord = 0;
    private static int edellinenPohjkoord = 0;
    private static String line;
    private static int rivinumeroNyt = 0;
    private static ArrayList<Pistevuosi> pvLista = new ArrayList<Pistevuosi>();
    private static ArrayList<Havaintopiste> hpLista = new ArrayList<Havaintopiste>();
    private static int suurinPisteidenLkmReitilla = 20;
    private static HashMap<String, Lajihavainto> lhMap = new HashMap<String, Lajihavainto>();
    /*******************************************
     * Logiprinttien päälle kytkentä -muuttuja *
     *******************************************/
    private static final boolean logiTulostus = false;

    /*
     * Sade25m luo omasta tiedostostaan listan poikkeuksellisista pisteistä
     * joilla säde on 25 metriä.
     */
    public PulautinV3() throws FileNotFoundException, java.io.IOException {
        Sade25m.luoPoikkeusOliot();
        aloitaluku();
    }


    /*
     * Palauttaa havainnointikokonaisuus -olion, joka sisältää yhden havainnoinnin tiedot tietokantaa varten.
     */
    public Havainnointikokonaisuus getHK() {
        return hk;
    }

    /*
     * Luo havainnointikokonaisuus -olion. Tuottaa yhden Reitin kaikki tiedot kerrallaan.
     */
    public static void tuotaHavainnointikokonaisuusOlio() throws FileNotFoundException, java.io.IOException {
        hk = new Havainnointikokonaisuus();
        if (!lukeminenAloitettu) {
            line = buffreader.readLine();
            lukeminenAloitettu = true;
        }

        while (line != null && !onkoDataLoppunut) {
            rivinumeroNyt++;
            //content.append(line).append("/n");
            String rivi = line.toString();
            if (onkoPistetietoRivi(rivi)) {
                tuotaPistetietoRivi(rivi);
            } else { //jos rivi ei ole pistetietorivi, niin kyseessä siis reitin "otsakerivi"
                int nykyinenReitti = Integer.parseInt(rivi.substring(0, 4));
                if (rivinumeroNyt > 1 && aikaisempiParsittavaReitti != nykyinenReitti) { //mikäli reitin numero vaihtuu, on tämän reitin kokonaisuus paketissa ja breakataan
                    reittiVaihtunut = true;
                    rivinumeroNyt = 0;
                    break;
                }

                jatkoriveja = 0;
                jatkorivi = "";
                if (onkoJatkoriveja(rivi)) {
                    jatkorivi = buffreader.readLine().toString();
                    jatkoriveja++;
                }
                tuotaReittiHavainnointitapahtumaHavaintopisteetJaParvihavainnot(rivi);
            }
            line = buffreader.readLine();
            if (line == null) {
                onkoDataLoppunut = true;
            }
        }
    }

    /*
     * Ei käytössä.
     */
    public static Havainnointikokonaisuus parsaaAineistoKokonaan() throws FileNotFoundException, java.io.IOException {

        while ((line = buffreader.readLine()) != null) {
            //tulostaLogiinLN("rivi:"+line.toString()+"/n");
            String rivi = line.toString();
            if (onkoPistetietoRivi(rivi)) {
                tuotaPistetietoRivi(rivi);
            } else {
                jatkoriveja = 0;
                jatkorivi = "";
                if (onkoJatkoriveja(rivi)) {
                    jatkorivi = buffreader.readLine().toString();
                    jatkoriveja++;
                }
                tuotaReittiHavainnointitapahtumaHavaintopisteetJaParvihavainnot(rivi);
            }
        }
        return hk;
    }

    /*
     * Aseta perättäistiedoston polku FileInputStreamin parametriksi.
     */
    public static void aloitaluku() throws FileNotFoundException {
        FileInputStream file = new FileInputStream("/fs-0/0/amjaalto/Linnut/trunk/Linnutrokkaa/PISTEET.DAT");//"C:/PISTEET.DAT");
        DataInputStream in = new DataInputStream(file);
        buffreader = new BufferedReader(new InputStreamReader(in, charset), 50000000);

    }

    /*
     * Testimain
     */
    public static void main(String[] args) throws FileNotFoundException, java.io.IOException {
        //init();
        //StringBuilder content = new StringBuilder();
        Sade25m.luoPoikkeusOliot();
        aloitaluku();
        //parsaaAineistoKokonaan();
        for (int i = 0; i < 280; i++) {
            tuotaHavainnointikokonaisuusOlio();
        }
//        ArrayList<Reitti> Reittilista = new ArrayList<Reitti>();
//        Reittilista = hk.getReitti();
//        tulostaLogiinLN("Reittejä reittilistassa (pitäisi olla 1): " + Reittilista.size());
//        Reitti reitti3 = Reittilista.remove(0);
//        tulostaLogiinLN("Reitillä on havaintoja näin monelta vuodelta: " + reitti3.getHavainnointitapahtumat().size());
//        tuotaHavainnointikokonaisuusOlio();
//        Reittilista = hk.getReitti();
//        tulostaLogiinLN("Reittejä reittilistassa (pitäisi olla 1): " + Reittilista.size());
//        reitti3 = Reittilista.remove(0);
//        tulostaLogiinLN("Reitillä on havaintoja näin monelta vuodelta: " + reitti3.getHavainnointitapahtumat().size());

    }

    /*
     * Kertoo ollaanko tiedoston lopussa.
     */
    public static boolean onkoDataLoppunut() {
        return onkoDataLoppunut;
    }

    /*
    Purkaa vanhasta datasta otsakerivin joita on 1 per havainnointi ja mahdollinen
    jatkorivi. Tällä metodilla luodaan parvihavainto-olioita liittyen pisteen
    numeroon. Laskee parvien määrän ja kutsuu tuotaJatkoRivi -metodia, jolla tuotetaan
    loput parvihavainto-oliot, mikäli parvihavaintoja on enemmän kuin 2 kpl.
     */
    private static void tuotaReittiHavainnointitapahtumaHavaintopisteetJaParvihavainnot(String rivi) {

        ht = new Havainnointitapahtuma();
        int parvia;
        int reitinNumero = Integer.parseInt(rivi.substring(0, 4));
        aikaisempiParsittavaReitti = reitinNumero;
        tulostaLogiin("Reitin numero: " + reitinNumero + ",");
        int vuosi = Integer.parseInt(rivi.substring(4, 8));
        int havannoijaNumero = intParseri(rivi.substring(10, 14));
        String peninkulmaRuutu = rivi.substring(14, 19);

        String pohjoisKoord = peninkulmaRuutu.substring(0, 3);
        String itaKoord = "3" + peninkulmaRuutu.substring(3, 5);

        int itakoordinaatti = intParseri(itaKoord);
        int pohjoiskoordinaatti = intParseri(pohjoisKoord);

        /*
         * Tarkistetaan vaihteleeko koordinaatit reitin sisällä (ei pitäisi)
         * eikä näyttäisi vaihtelevankaan.
         */
        if (!reittiVaihtunut) {
            vertaaKoordinaatteja(itakoordinaatti, pohjoiskoordinaatti);
        }

        edellinenItakoord = itakoordinaatti;
        edellinenPohjkoord = pohjoiskoordinaatti;

        tulostaLogiin("Peninkulmaruutu: " + peninkulmaRuutu + ",");
        String kuntaLyhenne = rivi.substring(19, 25);
        tulostaLogiin("Kuntalyhenne: " + kuntaLyhenne + ",");
        String pisteidenLkm = rivi.substring(25, 27);
        tulostaLogiin("Pisteiden lukumäärä: " + pisteidenLkm + ",");
        String lahempiPaikka = rivi.substring(27, 44);
        lahempiPaikka = lahempiPaikka.trim();
        tulostaLogiin("Lähempi paikka: " + lahempiPaikka + ",");
        String talvireitinNro = rivi.substring(44, 48);
        talvireitinNro = talvireitinNro.trim();
        //poista nollat
        tulostaLogiin("Talvireitin numero: " + talvireitinNro + ",");
        String laskPaiva = rivi.substring(48, 50);
        tulostaLogiin("Laskentapäivä: " + laskPaiva + ",");
        String laskKK = poistaAlkuNollat(rivi.substring(50, 51));
        tulostaLogiin("Laskentakuukausi: " + laskKK + ",");
        String laskentaAlkoiString = rivi.substring(51, 55);
        int alkuTunnit = intParseri(laskentaAlkoiString.substring(0, 2).trim());
        int alkuMinuutit = intParseri(laskentaAlkoiString.substring(2, 4).trim());
        //HUOM: minuutit "04" tallentuu nyt vain muotoon "4" (muotoilu-issue)
        tulostaLogiin("Laskenta alkoi: " + laskentaAlkoiString + ",");
        //poista nollat
        String laskentaLoppuiString = rivi.substring(55, 59);
        int loppuTunnit = Integer.parseInt(laskentaLoppuiString.substring(0, 2).trim());
        int loppuMinuutit = Integer.parseInt(laskentaLoppuiString.substring(2, 4).trim());
        tulostaLogiin("Laskenta loppui: " + laskentaLoppuiString + ",");
        //poista nollat
        tulostaLogiin("\n");
        parvia = 0;


        /*
         * Jos reitti on vaihtunut, on siis kyseessä uusi reitti.
         */
        if (reittiVaihtunut) {
            rt = new Reitti();
        }

        rt.setVanhaReittiNumero(reitinNumero);
        rt.setTalvireitinNumero(intParseri(talvireitinNro));
        rt.setItakoordinaatti(itakoordinaatti);
        rt.setPohjoiskoordinaatti(pohjoiskoordinaatti);
        rt.setPisteidenLkm(intParseri(pisteidenLkm));

        ht.setLahempiPaikka(lahempiPaikka);
        ht.setLaskentakunta(kuntaLyhenne.trim());

        /*
         * Luodaan reitille pistevuodet
         */
        pvLista.clear();
        if (reittiVaihtunut) {
            hpLista.clear();
            suurinPisteidenLkmReitilla = intParseri(pisteidenLkm);
        }

        for (int i = 0; i < intParseri(pisteidenLkm); i++) {
            Pistevuosi pv = new Pistevuosi();
            if (reittiVaihtunut) {
                hp = new Havaintopiste();
                hpLista.add(hp);
                rt.addHavaintopiste(hp);
                hp.addReitti(rt);
                hk.lisaaHavaintopiste(hp);

            }
            if (suurinPisteidenLkmReitilla < intParseri(pisteidenLkm) && i > suurinPisteidenLkmReitilla - 1) {
                hp = new Havaintopiste();
                hpLista.add(hp);
                rt.addHavaintopiste(hp);
                hk.lisaaHavaintopiste(hp);

            }
            hp = hpLista.get(i);

            ht.addPistevuosi(pv);
            pv.setHavainnointitapahtuma(ht);
            hp.addPistevuosi(pv);
            pv.setHavaintopiste(hp);
            pv.setReitinNumero(reitinNumero);
            pv.setPisteenJarjestysnumero(i + 1);
            pv.setVuosi(vuosi);

            if (Sade25m.tarkistaOnko25mSade(reitinNumero, vuosi, i + 1)) {
                pv.setReitinSade(25);
            } else {
                pv.setReitinSade(50);
            }

            pvLista.add(pv);
            hk.lisaaPistevuosi(pv);
        }


        if (suurinPisteidenLkmReitilla < intParseri(pisteidenLkm)) {
            suurinPisteidenLkmReitilla = intParseri(pisteidenLkm);
        }


        /*
         * Tuotetaan nyt havainnointitapahtuma-olio
         */

        ht.setHavainnoijaNumero(havannoijaNumero);
        ht.setVuosi(vuosi);
        ht.setKuukausi(intParseri(laskKK));
        ht.setPaiva(intParseri(laskPaiva));
        ht.setAlkuTunnit(alkuTunnit);
        ht.setLoppuTunnit(loppuTunnit);
        ht.setAlkuMinuutit(alkuMinuutit);
        ht.setLoppuMinuutit(loppuMinuutit);
        ht.setReitti(rt);

        /*
         * Lisätään luotu havainnointitapahtuma ja reitti havainnointikokonaisuuteen
         */
        tulostaLogiinLN(ht.toString());
        hk.lisaaHavainnointitapahtuma(ht);
        if (reittiVaihtunut) {
            hk.lisaaReitti(rt);
            reittiVaihtunut = false;
        }


        if (jatkoriveja > 0) {
            jatkorivi = jatkorivi.trim();

            if (jatkorivi.length() > 52) {
                parvia = 6;
            } else if (jatkorivi.length() > 41) {
                parvia = 5;
            } else if (jatkorivi.length() > 30) {
                parvia = 4;
            } else if (jatkorivi.length() > 19) {
                parvia = 3;
            }
        } else if (rivi.length() > 62) {
            parvia = 1;
        } else if (rivi.length() > 75) {
            parvia = 2;
        } else {
            parvia = 0;
        }
        tulostaLogiinLN("Parvihavaintoja: " + parvia);
        tuotaParvihavaintoAlku(rivi, parvia);
        if (jatkoriveja > 0) {
            tuotaParvihavaintoLoppu(jatkorivi, parvia);
        }

        tulostaLogiin("\n");
        tulostaLogiin("\n");

    }

    /*
     * Purkaa vanhasta datasta pistetietorivit, eli pisteisiin liittyvät lajihavainnot.
     * Näistä luodaan lajihavainto-olioita liittyen pisteen numeroon.
     */
    private static void tuotaPistetietoRivi(String rivi) {
        tulostaLogiinLN("*** Pistetietorivi: " + rivi + " ****");
        tulostaLogiin("Reitti: " + rivi.substring(0, 4) + ", vuosi:" + rivi.substring(4, 8) + ", (juoksevanro):" + poistaAlkuNollat(rivi.substring(8, 10)) + ", ");
        rivi = rivi.trim();
        int pisteHLkm = 0;
        if (rivi.length() > 76) {
            pisteHLkm = 8;
        } else if (rivi.length() > 76) {
            pisteHLkm = 7;
        } else if (rivi.length() > 68) {
            pisteHLkm = 7;
        } else if (rivi.length() > 60) {
            pisteHLkm = 6;
        } else if (rivi.length() > 52) {
            pisteHLkm = 5;
        } else if (rivi.length() > 44) {
            pisteHLkm = 4;
        } else if (rivi.length() > 36) {
            pisteHLkm = 3;
        } else if (rivi.length() > 30) {
            pisteHLkm = 2;
        } else if (rivi.length() > 23) {
            pisteHLkm = 1;
        }

        int j = 0;

        int biotooppiNyt = biotooppiparseri(rivi.substring(10, 12));

        int biotooppiEnnen = biotooppiparseri((rivi.substring(12, 14)));
        int pisteNro = intParseri(poistaAlkuNollat(rivi.substring(14, 16)));

        tulostaLogiin("lajihavaintoja:" + pisteHLkm + " \n");

        /*
         * HAETAAN PISTEVUOSIOLIO PV NUMEROLLA PULAUTTIMEN SISÄISESTÄ LISTASTA JA ASETETAAN PV VIITTAAMAAN SIIHEN
         */
        pv = pvLista.get(pisteNro - 1);
        pv.setBiotooppikoodiEnnen(biotooppiEnnen);
        pv.setBiotooppikoodiNyt(biotooppiNyt);
        pv.setPisteenJarjestysnumero(pisteNro);
        hp = hpLista.get(pisteNro - 1);
        hp.addPistevuosi(pv);
        pv.setHavaintopiste(hp);
        lhMap.clear();

        tulostaLogiin("Piste: " + pisteNro + ", biotooppi: " + biotooppiNyt + ", biotooppi vuosi sitten: " + biotooppiEnnen + ", lintuhavaintoja: " + pisteHLkm + " kpl: \n");
        tulostaLogiin("Luo seuraavat lajihavainto-oliot: *** ");
        for (int i = 0; i < pisteHLkm; i++) {
            String oliodata = rivi.substring(16 + j, 24 + j);
            j = j + 8;
            int parimaaraSisapuolella = intParseri(oliodata.substring(0, 1));
            int parimaaraUlkopuolella = intParseri(oliodata.substring(1, 2));
            String lajiLyhenne = oliodata.substring(2, 8);

            /*
             * Luodaan varsinaiset lajihavainto-oliot
             */

            if (!Character.isWhitespace(lajiLyhenne.charAt(0))) {


                /*********************************************************************************
                 * Tarkastetaan ettei samasta pisteestä löydy useampaa havaintoa samasta lajista *
                 *********************************************************************************/
                if (lhMap.containsKey(lajiLyhenne)) {
                    Lajihavainto apuLh = new Lajihavainto();
                    apuLh = lhMap.get(lajiLyhenne);


                    System.out.println("Löytyi aiempi havainto samalta pisteeltä lajilla: " + lajiLyhenne);

                    int lmSisapuolella = apuLh.getParimaaraSisapuolella();
                    int lmUlkopuolella = apuLh.getParimaaraUlkopuolella();

                    apuLh.setParimaaraSisapuolella(lmSisapuolella + parimaaraSisapuolella);
                    apuLh.setParimaaraUlkopuolella(lmUlkopuolella + parimaaraUlkopuolella);

                } else {

                    Lajihavainto lh = new Lajihavainto();
                    lh.setPisteenNumero(pisteNro);
                    lh.setParvilaji(lajiLyhenne);
                    lh.setParimaaraSisapuolella(parimaaraSisapuolella);
                    lh.setParimaaraUlkopuolella(parimaaraUlkopuolella);
                    lh.setPistevuosi(pv);


                    lhMap.put(lajiLyhenne, (Lajihavainto) lh);

                    hk.lisaaLajihavainto(lh);
                    tulostaLogiin("Laji:" + lajiLyhenne + ", ");
                    tulostaLogiin("lkm sis.:" + parimaaraSisapuolella + ", ");
                    tulostaLogiin("lkm ulkop.:" + parimaaraUlkopuolella + " ");
                    tulostaLogiin("*** ");
                }
            }

        }

        tulostaLogiinLN("\n");
    }

    /******************************************
     * Tunnistaa onko kyseessÃƒÂ¤ pistetietorivi *
     ******************************************/
    private static boolean onkoPistetietoRivi(String rivi) {
        String juoksevaNro = rivi.substring(8, 10);
        if (juoksevaNro.equals("01")) {
            //tulostaLogiinLN(rivi);
            return false;
        }
        return true;
    }

    /*****************************************************************************************
     * Tuottaa parvihavaintojen alkuosan. TÃ¤llÃ¤ metodilla luodaan 2 parvihavainto-oliota.  *
     *****************************************************************************************/
    private static void tuotaParvihavaintoAlku(String rivi, int parvia) {
        int vuosi = Integer.parseInt(rivi.substring(4, 8));

        //HAETAAN PISTEVUOSIOLIO PV NUMEROLLA PULAUTTIMEN SISÄISESTÄ LISTASTA JA ASETETAAN PV VIITTAAMAAN SIIHEN
        if (parvia > 0) {

            String parv1P = rivi.substring(59, 61);
            tulostaLogiin("EnsimmÃƒÂ¤isen parven piste: " + parv1P + ",");
            String parv1L = rivi.substring(61, 67);
            tulostaLogiin("EnsimmÃƒÂ¤isen parven laji: " + parv1L + ",");
            String parv1K = rivi.substring(67, 70);
            tulostaLogiin("EnsimmÃƒÂ¤isen parven koko: " + parv1K + ",");

            if (intParseri(parv1P) - 1 < 0) {
                tulostaLogiinLN("Tyhjäarvo datassa. Oletettu arvolle 1");
                pv = pvLista.get(0);
            } else {
                pv = pvLista.get(intParseri(parv1P) - 1);
            }

            if (!Character.isWhitespace(parv1L.charAt(0))) {
                Parvihavainto ph = new Parvihavainto();
                ph.setParvenKoko(intParseri(parv1K.trim()));
                ph.setParvilaji(parv1L);
                ph.setPistevuosi(pv);
                pv.addParvihavainto(ph);
                pv.setPisteenJarjestysnumero(intParseri(parv1P.trim()));
                hk.lisaaParvihavainto(ph);
            }
        }
        if (parvia > 1) {
            String parv2P = rivi.substring(70, 72);
            tulostaLogiin("Toisen parven piste: " + parv2P + ",");
            String parv2L = rivi.substring(72, 78);
            tulostaLogiin("Toisen parven laji: " + parv2L + ",");
            String parv2K = rivi.substring(78, 81);
            tulostaLogiin("Toisen parven koko: " + parv2K + ",");

            if (!Character.isWhitespace(parv2L.charAt(0))) {
                pv = pvLista.get(intParseri(parv2P) - 1);
                Parvihavainto ph = new Parvihavainto();
                ph.setParvenKoko(intParseri(parv2K.trim()));
                ph.setParvilaji(parv2L);
                ph.setPistevuosi(pv);
                pv.addParvihavainto(ph);
                pv.setPisteenJarjestysnumero(intParseri(parv2P.trim()));
                hk.lisaaParvihavainto(ph);
            }
        }
    }

    /***********************************************************************************************************
     * Tuottaa parvihavaintojen jatkorivin. TÃ¤llÃ¤ luodaan tarvittaessa loput parvihavainto-olioista (max 4kpl) *
     ***********************************************************************************************************/
    private static void tuotaParvihavaintoLoppu(String rivi, int parvia) {

        //HAETAAN PISTEVUOSIOLIO PV NUMEROLLA PULAUTTIMEN SISÄISESTÄ LISTASTA JA ASETETAAN PV VIITTAAMAAN SIIHEN


        if (parvia > 2) {

            String parv3P = rivi.substring(10, 12);
            tulostaLogiin("Kolmannen parven piste: " + parv3P + ",");
            String parv3L = rivi.substring(12, 18);
            tulostaLogiin("Kolmannen parven laji: " + parv3L + ",");
            String parv3K = rivi.substring(18, 21);
            tulostaLogiin("Kolmannen parven koko: " + parv3K + ",");

            if (!Character.isWhitespace(parv3L.charAt(0))) {
                pv = pvLista.get(intParseri(parv3P) - 1);
                Parvihavainto ph = new Parvihavainto();
                ph.setParvenKoko(intParseri(parv3K.trim()));
                ph.setParvilaji(parv3L);
                ph.setPistevuosi(pv);
                pv.addParvihavainto(ph);
                pv.setPisteenJarjestysnumero(intParseri(parv3P.trim()));
                hk.lisaaParvihavainto(ph);
            }
        }
        if (parvia > 3) {
            String parv4P = rivi.substring(21, 23);
            tulostaLogiin("NeljÃƒÂ¤nnen parven piste: " + parv4P + ",");
            String parv4L = rivi.substring(23, 29);
            tulostaLogiin("NeljÃƒÂ¤nnen parven laji: " + parv4L + ",");
            String parv4K = rivi.substring(29, 32);
            tulostaLogiin("NeljÃƒÂ¤nnen parven koko: " + parv4K + ",");

            if (!Character.isWhitespace(parv4L.charAt(0))) {
                pv = pvLista.get(intParseri(parv4P) - 1);
                Parvihavainto ph = new Parvihavainto();
                ph.setParvenKoko(intParseri(parv4K.trim()));
                ph.setParvilaji(parv4L);
                ph.setPistevuosi(pv);
                pv.addParvihavainto(ph);
                pv.setPisteenJarjestysnumero(intParseri(parv4P.trim()));
                hk.lisaaParvihavainto(ph);
            }
        }
        if (parvia > 4) {
            String parv5P = rivi.substring(32, 34);
            tulostaLogiin("Viidennen parven piste: " + parv5P + ",");
            String parv5L = rivi.substring(34, 40);
            tulostaLogiin("Viidennen parven laji: " + parv5L + ",");
            String parv5K = rivi.substring(40, 43);
            tulostaLogiin("Viidennen parven koko: " + parv5K + ",");

            if (!Character.isWhitespace(parv5L.charAt(0))) {
                pv = pvLista.get(intParseri(parv5P) - 1);
                Parvihavainto ph = new Parvihavainto();
                ph.setParvenKoko(intParseri(parv5K.trim()));
                ph.setParvilaji(parv5L);
                ph.setPistevuosi(pv);
                pv.addParvihavainto(ph);
                pv.setPisteenJarjestysnumero(intParseri(parv5P.trim()));
                hk.lisaaParvihavainto(ph);
            }
        }
        if (parvia > 5) {
            String parv6P = rivi.substring(43, 45);
            tulostaLogiin("Kuudennen parven piste: " + parv6P + ",");
            String parv6L = rivi.substring(45, 51);
            tulostaLogiin("Kuudennen parven laji: " + parv6L + ",");
            String parv6K = rivi.substring(51, 54);
            tulostaLogiin("Kuudennen parven koko: " + parv6K + ",");

            if (!Character.isWhitespace(parv6L.charAt(0))) {
                pv = pvLista.get(intParseri(parv6P) - 1);
                Parvihavainto ph = new Parvihavainto();
                ph.setParvenKoko(intParseri(parv6K.trim()));
                ph.setParvilaji(parv6L);
                ph.setPistevuosi(pv);
                pv.addParvihavainto(ph);
                pv.setPisteenJarjestysnumero(intParseri(parv6P.trim()));
                hk.lisaaParvihavainto(ph);
            }
        }
    }

    /***********************************************************************************************
     * Tulostusmetodi rivinvaihdottomalle riville ja mahd. myöhemmin lokitiedostoon tallennukseeen *
     ***********************************************************************************************/
    private static void tulostaLogiin(String viesti) {
        if (logiTulostus) {
            System.out.print(viesti);
        }
    }

    /***********************************************************************************************
     * Tulostusmetodi rivinvaihdolliselle riville ja mahd. myöhemmin lokitiedostoon tallennukseeen *
     ***********************************************************************************************/
    private static void tulostaLogiinLN(String viesti) {
        if (logiTulostus) {
            System.out.println(viesti);
        }
    }

    /****************************************************************
     * Tunnistaa onko kyseisellÃƒÂ¤ rivillÃƒÂ¤ jatkorivi lisÃƒÂ¤havainnoille *
     ****************************************************************/
    private static boolean onkoJatkoriveja(String rivi) {
        if (rivi.length() == 82) {
            if (rivi.charAt(81) == tahti) {
                //tulostaLogiinLN("TÃƒHTI");
                //tulostaLogiinLN(rivi);
                return true;
            }
        }
        //if (rivi.charAt(60)==tahti)tulostaLogiinLN("TÃƒHTI");
        return false;
    }

    /**************************
     * Poistaa nollat alusta. *
     **************************/
    private static String poistaAlkuNollat(String rivi) {
        if (rivi.charAt(0) == nolla) {
            rivi = rivi.substring(1, rivi.length());
        }
        //else if (Character.isWhitespace(rivi.charAt(0)))rivi.substring(1, rivi.length());
        return rivi;
    }

    private static boolean vertaaKoordinaatteja(int ita, int pohj) {
        if (ita == edellinenItakoord) {
            if (pohj == edellinenPohjkoord) {
                return true;
            }
        }

        System.out.println("koordinaatit muuttuneet välissä");

        return false;



    }

    /***********************************
     * Parsettaa stringistä int-arvoja *
     ***********************************/
    private static int intParseri(String parsettava) {
        //tulostaLogiinLN("SAATU: *"+parsettava+"*");
        if (parsettava.length() == 1 && parsettava.charAt(0) == ' ')
            return 0;
        try {
            if (parsettava.length() > 0) {
                if (Character.isWhitespace(parsettava.charAt(0))) {
                    parsettava = parsettava.trim();
                }
                //tulostaLogiinLN("PARSETTU: *"+parsettava+"*");
                return Integer.parseInt((parsettava));

            } else {
                //ARVO PUUTTUU
                //tulostaLogiinLN("PARSETTU: *-1*");
                return -1;
            }
        } catch (NumberFormatException e) {

            return -2;

        }
    }

    private static int biotooppiparseri(String parsettava) {
        if (parsettava.length() == 1 && parsettava.charAt(0) == ' ')
            return 0;
        if (parsettava.length() == 2 && parsettava.charAt(0) == ' ' && parsettava.charAt(1) == ' ')
            return 0;
        int numerona = intParseri(parsettava.trim());
        if (numerona == 99)
            return 0;
        return numerona;
    }
}
